home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / frasrc19.zip / PROMPTS1.C < prev    next >
C/C++ Source or Header  |  1995-02-25  |  70KB  |  2,367 lines

  1. /*
  2.     Various routines that prompt for things.
  3. */
  4.  
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #ifndef XFRACT
  10. #include <dos.h>
  11. #elif !defined(__386BSD__)
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include <sys/dir.h>
  15. #endif
  16. #ifdef __TURBOC__
  17. #include <alloc.h>
  18. #elif !defined(__386BSD__)
  19. #include <malloc.h>
  20. #endif
  21.  
  22. #ifdef __hpux
  23. #include <sys/param.h>
  24. #define getwd(a) getcwd(a,MAXPATHLEN)
  25. #endif
  26.  
  27. #include "fractint.h"
  28. #include "fractype.h"
  29. #include "helpdefs.h"
  30. #include "prototyp.h"
  31.  
  32. /* Routines used in prompts2.c */
  33.  
  34.     int prompt_checkkey(int curkey);
  35.     long get_file_entry(int,char *,char *,char *,char *);
  36.  
  37. /* Routines in this module    */
  38.  
  39. int prompt_valuestring(char *buf,struct fullscreenvalues *val);
  40. static    int input_field_list(int attr,char *fld,int vlen,char **list,int llen,
  41.                  int row,int col,int (*checkkey)(int));
  42. static    int select_fracttype(int t);
  43. static    int sel_fractype_help(int curkey, int choice);
  44.     int select_type_params(int newfractype,int oldfractype);
  45.           void set_default_parms(void);
  46. static    long gfe_choose_entry(int,char *,char *,char *);
  47. static    int check_gfe_key(int curkey,int choice);
  48. static    void load_entry_text(FILE *entfile,char far *buf,int maxlines);
  49. static    void format_parmfile_line(int,char *);
  50. static    int get_light_params(void );
  51. static    int check_mapfile(void );
  52. static    int get_funny_glasses_params(void );
  53.  
  54. /* fullscreen_choice options */
  55. #define CHOICEHELP    4
  56.  
  57. #define GETFORMULA 0
  58. #define GETLSYS    1
  59. #define GETIFS       2
  60. #define GETPARM    3
  61.  
  62. static char funnyglasses_map_name[16];
  63. char ifsmask[13]     = {"*.ifs"};
  64. char formmask[13]    = {"*.frm"};
  65. char lsysmask[13]    = {"*.l"};
  66. char Glasses1Map[] = "glasses1.map";
  67. char MAP_name[80] = "";
  68. int  mapset = 0;
  69. int julibrot;   /* flag for julibrot */
  70.  
  71. /* --------------------------------------------------------------------- */
  72.  
  73. int promptfkeys;
  74.  
  75. int fullscreen_prompt(    /* full-screen prompting routine */
  76.     char far *hdg,        /* heading, lines separated by \n */
  77.     int numprompts,     /* there are this many prompts (max) */
  78.     char far **prompts,     /* array of prompting pointers */
  79.     struct fullscreenvalues *values, /* array of values */
  80.     int fkeymask,        /* bit n on if Fn to cause return */
  81.     char far *extrainfo    /* extra info box to display, \n separated */
  82.     )
  83. {
  84.    char far *hdgscan;
  85.    int titlelines,titlewidth,titlerow;
  86.    int maxpromptwidth,maxfldwidth,maxcomment;
  87.    int boxrow,boxlines;
  88.    int boxcol,boxwidth;
  89.    int extralines,extrawidth,extrarow;
  90.    int instrrow;
  91.    int promptrow,promptcol,valuecol;
  92.    int curchoice;
  93.    int done, i, j;
  94.    int anyinput;
  95.    int savelookatmouse;
  96.    int curtype, curlen;
  97.    char buf[81];
  98. #ifndef XFRACT
  99. static FCODE instr1[]  = {"Use " UPARR " and " DNARR " to select values to change"};
  100. static FCODE instr2a[]  = {"Type in replacement value for selected field"};
  101. static FCODE instr2b[]  = {"Use " LTARR " or " RTARR " to change value of selected field"};
  102. #else
  103. /* Some compilers don't accept "a" "b", so we have to fill in UPARR ourself.  */
  104. static char far instr1[]  = {"Use up(K) and down(J) to select values to change"};
  105. static char far instr2a[]  = {"Type in replacement value for selected field"};
  106. static char far instr2b[]  = {"Use left(H) or right(L) to change value of selected field"};
  107. #endif
  108. static FCODE instr3a[] = {"Press ENTER when finished (or ESCAPE to back out)"};
  109. static FCODE instr3b[] = {"Press ENTER when finished, ESCAPE to back out, or F1 for help"};
  110. static FCODE instr0a[] = {"No changeable parameters; press ENTER to exit"};
  111. static FCODE instr0b[] = {"No changeable parameters; press ENTER to exit, ESCAPE to back out, F1 for help"};
  112. /*   if (numprompts <= 0) { */    /* ?? nothing to do! */
  113. /*      return(0); */
  114. /*      } */
  115.    savelookatmouse = lookatmouse;
  116.    lookatmouse = 0;
  117.    promptfkeys = fkeymask;
  118.    helptitle();                /* clear screen, display title line  */
  119.    setattr(1,0,C_PROMPT_BKGRD,24*80);  /* init rest of screen to background */
  120.  
  121.    hdgscan = hdg;               /* count title lines, find widest */
  122.    i = titlewidth = 0;
  123.    titlelines = 1;
  124.    while (*hdgscan) {
  125.       if (*(hdgscan++) == '\n') {
  126.      ++titlelines;
  127.      i = -1;
  128.      }
  129.       if (++i > titlewidth)
  130.      titlewidth = i;
  131.       }
  132.    extralines = extrawidth = i = 0;
  133.    if ((hdgscan = extrainfo) != 0)
  134.       if (*hdgscan == 0)
  135.      extrainfo = NULL;
  136.       else { /* count extra lines, find widest */
  137.      extralines = 3;
  138.      while (*hdgscan) {
  139.         if (*(hdgscan++) == '\n') {
  140.            if (extralines + numprompts + titlelines >= 20) {
  141.            *hdgscan = 0; /* full screen, cut off here */
  142.            break;
  143.            }
  144.            ++extralines;
  145.            i = -1;
  146.            }
  147.         if (++i > extrawidth)
  148.            extrawidth = i;
  149.         }
  150.      }
  151.  
  152.    /* work out vertical positioning */
  153.    i = numprompts + titlelines + extralines + 3; /* total rows required */
  154.    j = (25 - i) / 2;               /* top row of it all when centered */
  155.    j -= j / 4;                   /* higher is better if lots extra */
  156.    boxlines = numprompts;
  157.    titlerow = 1 + j;
  158.    promptrow = boxrow = titlerow + titlelines;
  159.    if (titlerow > 2) {               /* room for blank between title & box? */
  160.       --titlerow;
  161.       --boxrow;
  162.       ++boxlines;
  163.       }
  164.    instrrow = boxrow+boxlines;
  165.    if (instrrow + 3 + extralines < 25) {
  166.       ++boxlines;    /* blank at bottom of box */
  167.       ++instrrow;
  168.       if (instrrow + 3 + extralines < 25)
  169.      ++instrrow; /* blank before instructions */
  170.       }
  171.    extrarow = instrrow + 2;
  172.    if (numprompts > 1) /* 3 instructions lines */
  173.       ++extrarow;
  174.    if (extrarow + extralines < 25)
  175.       ++extrarow;
  176.  
  177.    /* work out horizontal positioning */
  178.    maxfldwidth = maxpromptwidth = maxcomment = anyinput = 0;
  179.    for (i = 0; i < numprompts; i++) {
  180.       if (values[i].type == 'y') {
  181.      static char *noyes[2] = {s_no,s_yes};
  182.      values[i].type = 'l';
  183.      values[i].uval.ch.vlen = 3;
  184.      values[i].uval.ch.list = noyes;
  185.      values[i].uval.ch.llen = 2;
  186.      }
  187.       j = far_strlen(prompts[i]);
  188.       if (values[i].type == '*') {
  189.      if (j > maxcomment)     maxcomment = j;
  190.      }
  191.       else {
  192.          anyinput = 1;
  193.      if (j > maxpromptwidth) maxpromptwidth = j;
  194.      j = prompt_valuestring(buf,&values[i]);
  195.      if (j > maxfldwidth)     maxfldwidth = j;
  196.      }
  197.       }
  198.    boxwidth = maxpromptwidth + maxfldwidth + 2;
  199.    if (maxcomment > boxwidth) boxwidth = maxcomment;
  200.    if ((boxwidth += 4) > 80) boxwidth = 80;
  201.    boxcol = (80 - boxwidth) / 2;       /* center the box */
  202.    promptcol = boxcol + 2;
  203.    valuecol = boxcol + boxwidth - maxfldwidth - 2;
  204.    if (boxwidth <= 76) {           /* make margin a bit wider if we can */
  205.       boxwidth += 2;
  206.       --boxcol;
  207.       }
  208.    if ((j = titlewidth) < extrawidth)
  209.       j = extrawidth;
  210.    if ((i = j + 4 - boxwidth) > 0) {   /* expand box for title/extra */
  211.       if (boxwidth + i > 80)
  212.      i = 80 - boxwidth;
  213.       boxwidth += i;
  214.       boxcol -= i / 2;
  215.       }
  216.    i = (90 - boxwidth) / 20;
  217.    boxcol    -= i;
  218.    promptcol -= i;
  219.    valuecol  -= i;
  220.  
  221.    /* display box heading */
  222.    for (i = titlerow; i < boxrow; ++i)
  223.       setattr(i,boxcol,C_PROMPT_HI,boxwidth);
  224.    textcbase = boxcol + (boxwidth - titlewidth) / 2;
  225.    putstring(titlerow,0,C_PROMPT_HI,hdg);
  226.  
  227.    /* display extra info */
  228.    if (extrainfo) {
  229. #ifndef XFRACT
  230. #define S1 '\xC4'
  231. #define S2 "\xC0"
  232. #define S3 "\xD9"
  233. #define S4 "\xB3"
  234. #define S5 "\xDA"
  235. #define S6 "\xBF"
  236. #else
  237. #define S1 '-'
  238. #define S2 "+" /* ll corner */
  239. #define S3 "+" /* lr corner */
  240. #define S4 "|"
  241. #define S5 "+" /* ul corner */
  242. #define S6 "+" /* ur corner */
  243. #endif
  244.       memset(buf,S1,80); buf[boxwidth-2] = 0;
  245.       textcbase = boxcol + 1;
  246.       putstring(extrarow,0,C_PROMPT_BKGRD,buf);
  247.       putstring(extrarow+extralines-1,0,C_PROMPT_BKGRD,buf);
  248.       --textcbase;
  249.       putstring(extrarow,0,C_PROMPT_BKGRD,S5);
  250.       putstring(extrarow+extralines-1,0,C_PROMPT_BKGRD,S2);
  251.       textcbase += boxwidth - 1;
  252.       putstring(extrarow,0,C_PROMPT_BKGRD,S6);
  253.       putstring(extrarow+extralines-1,0,C_PROMPT_BKGRD,S3);
  254.       textcbase = boxcol;
  255.       for (i = 1; i < extralines-1; ++i) {
  256.          putstring(extrarow+i,0,C_PROMPT_BKGRD,S4);
  257.          putstring(extrarow+i,boxwidth-1,C_PROMPT_BKGRD,S4);
  258.      }
  259.       textcbase += (boxwidth - extrawidth) / 2;
  260.       putstring(extrarow+1,0,C_PROMPT_TEXT,extrainfo);
  261.       }
  262.    textcbase = 0;
  263.  
  264.    /* display empty box */
  265.    for (i = 0; i < boxlines; ++i)
  266.       setattr(boxrow+i,boxcol,C_PROMPT_LO,boxwidth);
  267.  
  268.    /* display initial values */
  269.    for (i = 0; i < numprompts; i++) {
  270.       putstring(promptrow+i, promptcol, C_PROMPT_LO, prompts[i]);
  271.       prompt_valuestring(buf,&values[i]);
  272.       putstring(promptrow+i, valuecol, C_PROMPT_LO, buf);
  273.       }
  274.  
  275.    if (!anyinput) {
  276.       putstringcenter(instrrow,0,80,C_PROMPT_BKGRD,
  277.         (helpmode > 0) ? instr0b : instr0a);
  278.       movecursor(25,80);
  279.       for(;;) {
  280.         while (!keypressed()) { }
  281.         done = getakey();
  282.         switch(done) {
  283.            case ESC:
  284.               done = -1;
  285.            case ENTER:
  286.            case ENTER_2:
  287.               goto fullscreen_exit;
  288.            case F2:
  289.            case F3:
  290.            case F4:
  291.            case F5:
  292.            case F6:
  293.            case F7:
  294.            case F8:
  295.            case F9:
  296.            case F10:
  297.               if (promptfkeys & (1<<(done+1-F1)) )
  298.                  goto fullscreen_exit;
  299.            }
  300.         }
  301.       }
  302.  
  303.  
  304.    /* display footing */
  305.    if (numprompts > 1)
  306.       putstringcenter(instrrow++,0,80,C_PROMPT_BKGRD,instr1);
  307.    putstringcenter(instrrow+1,0,80,C_PROMPT_BKGRD,
  308.      (helpmode > 0) ? instr3b : instr3a);
  309.  
  310.    curchoice = done = 0;
  311.    while (values[curchoice].type == '*') ++curchoice;
  312.  
  313.    while (!done) {
  314.  
  315.       curtype = values[curchoice].type;
  316.       curlen = prompt_valuestring(buf,&values[curchoice]);
  317.       putstringcenter(instrrow,0,80,C_PROMPT_BKGRD,
  318.               (curtype == 'l') ? instr2b : instr2a);
  319.       putstring(promptrow+curchoice,promptcol,C_PROMPT_HI,prompts[curchoice]);
  320.  
  321.       if (curtype == 'l') {
  322.      i = input_field_list(
  323.         C_PROMPT_CHOOSE, buf, curlen,
  324.         values[curchoice].uval.ch.list, values[curchoice].uval.ch.llen,
  325.         promptrow+curchoice,valuecol, prompt_checkkey);
  326.      for (j = 0; j < values[curchoice].uval.ch.llen; ++j)
  327.         if (strcmp(buf,values[curchoice].uval.ch.list[j]) == 0) break;
  328.      values[curchoice].uval.ch.val = j;
  329.      }
  330.       else {
  331.      j = 0;
  332.      if (curtype == 'i') j = 3;
  333.      if (curtype == 'L') j = 3;
  334.      if (curtype == 'd') j = 5;
  335.      if (curtype == 'D') j = 7;
  336.      if (curtype == 'f') j = 1;
  337.      i = input_field(j, C_PROMPT_INPUT, buf, curlen,
  338.         promptrow+curchoice,valuecol,prompt_checkkey);
  339.      switch (values[curchoice].type) {
  340.         case 'd':
  341.         case 'D':
  342.            values[curchoice].uval.dval = atof(buf);
  343.            break;
  344.         case 'f':
  345.            values[curchoice].uval.dval = atof(buf);
  346.            roundfloatd(&values[curchoice].uval.dval);
  347.            break;
  348.         case 'i':
  349.            values[curchoice].uval.ival = atoi(buf);
  350.            break;
  351.         case 'L':
  352.            values[curchoice].uval.Lval = atol(buf);
  353.            break;
  354.         case 's':
  355.            strncpy(values[curchoice].uval.sval,buf,16);
  356.            break;
  357.         default: /* assume 0x100+n */
  358.            far_strcpy(values[curchoice].uval.sbuf,buf);
  359.         }
  360.      }
  361.  
  362.       putstring(promptrow+curchoice,promptcol,C_PROMPT_LO,prompts[curchoice]);
  363.       j = strlen(buf);
  364.       memset(&buf[j],' ',80-j); buf[curlen] = 0;
  365.       putstring(promptrow+curchoice, valuecol, C_PROMPT_LO,  buf);
  366.  
  367.       switch(i) {
  368.      case 0:  /* enter  */
  369.         done = 13;
  370.         break;
  371.      case -1: /* escape */
  372.      case F2:
  373.      case F3:
  374.      case F4:
  375.      case F5:
  376.      case F6:
  377.      case F7:
  378.      case F8:
  379.      case F9:
  380.      case F10:
  381.         done = i;
  382.         break;
  383.      case PAGE_UP:
  384.         curchoice = -1;
  385.      case DOWN_ARROW:
  386.      case DOWN_ARROW_2:
  387.         do {
  388.            if (++curchoice >= numprompts) curchoice = 0;
  389.            } while (values[curchoice].type == '*');
  390.         break;
  391.      case PAGE_DOWN:
  392.         curchoice = numprompts;
  393.      case UP_ARROW:
  394.      case UP_ARROW_2:
  395.         do {
  396.            if (--curchoice < 0) curchoice = numprompts - 1;
  397.            } while (values[curchoice].type == '*');
  398.         break;
  399.      }
  400.       }
  401.  
  402. fullscreen_exit:
  403.    movecursor(25,80);
  404.    lookatmouse = savelookatmouse;
  405.    return(done);
  406. }
  407.  
  408. int prompt_valuestring(char *buf,struct fullscreenvalues *val)
  409. {  /* format value into buf, return field width */
  410.    int i,ret;
  411.    switch (val->type) {
  412.       case 'd':
  413.      ret = 20;
  414.      i = 16;    /* cellular needs 16 (was 15)*/
  415.      for(;;) {
  416.         sprintf(buf,"%.*g",i,val->uval.dval);
  417.         if ((int)strlen(buf) <= ret) break;
  418.         --i;
  419.         }
  420.      break;
  421.       case 'D':
  422.      if (val->uval.dval<0) { /* We have to round the right way */
  423.          sprintf(buf,"%ld",(long)(val->uval.dval-.5));
  424.      }
  425.      else {
  426.          sprintf(buf,"%ld",(long)(val->uval.dval+.5));
  427.      }
  428.      ret = 20;
  429.      break;
  430.       case 'f':
  431.      sprintf(buf,"%.7g",val->uval.dval);
  432.      ret = 14;
  433.      break;
  434.       case 'i':
  435.      sprintf(buf,"%d",val->uval.ival);
  436.      ret = 6;
  437.      break;
  438.       case 'L':
  439.      sprintf(buf,"%ld",val->uval.Lval);
  440.      ret = 10;
  441.      break;
  442.       case '*':
  443.      *buf = (char)(ret = 0);
  444.      break;
  445.       case 's':
  446.      strncpy(buf,val->uval.sval,16);
  447.      buf[15] = 0;
  448.      ret = 15;
  449.      break;
  450.       case 'l':
  451.      strcpy(buf,val->uval.ch.list[val->uval.ch.val]);
  452.      ret = val->uval.ch.vlen;
  453.      break;
  454.       default: /* assume 0x100+n */
  455.      far_strcpy(buf,val->uval.sbuf);
  456.      ret = val->type & 0xff;
  457.       }
  458.    return ret;
  459. }
  460.  
  461. int prompt_checkkey(int curkey)
  462. {
  463.    switch(curkey) {
  464.       case PAGE_UP:
  465.       case DOWN_ARROW:
  466.       case DOWN_ARROW_2:
  467.       case PAGE_DOWN:
  468.       case UP_ARROW:
  469.       case UP_ARROW_2:
  470.      return(curkey);
  471.       case F2:
  472.       case F3:
  473.       case F4:
  474.       case F5:
  475.       case F6:
  476.       case F7:
  477.       case F8:
  478.       case F9:
  479.       case F10:
  480.      if (promptfkeys & (1<<(curkey+1-F1)) )
  481.         return(curkey);
  482.       }
  483.    return(0);
  484. }
  485.  
  486. static int input_field_list(
  487.     int attr,          /* display attribute */
  488.     char *fld,          /* display form field value */
  489.     int vlen,          /* field length */
  490.     char **list,          /* list of values */
  491.     int llen,          /* number of entries in list */
  492.     int row,          /* display row */
  493.     int col,          /* display column */
  494.     int (*checkkey)(int)  /* routine to check non data keys, or NULL */
  495.     )
  496. {
  497.    int initval,curval;
  498.    char buf[81];
  499.    int curkey;
  500.    int i, j;
  501.    int ret,savelookatmouse;
  502.    savelookatmouse = lookatmouse;
  503.    lookatmouse = 0;
  504.    for (initval = 0; initval < llen; ++initval)
  505.       if (strcmp(fld,list[initval]) == 0) break;
  506.    if (initval >= llen) initval = 0;
  507.    curval = initval;
  508.    ret = -1;
  509.    for(;;) {
  510.       strcpy(buf,list[curval]);
  511.       i = strlen(buf);
  512.       while (i < vlen)
  513.      buf[i++] = ' ';
  514.       buf[vlen] = 0;
  515.       putstring(row,col,attr,buf);
  516.       curkey = keycursor(row,col); /* get a keystroke */
  517.       switch (curkey) {
  518.      case ENTER:
  519.      case ENTER_2:
  520.         ret = 0;
  521.         goto inpfldl_end;
  522.      case ESC:
  523.         goto inpfldl_end;
  524.      case RIGHT_ARROW:
  525.      case RIGHT_ARROW_2:
  526.         if (++curval >= llen)
  527.            curval = 0;
  528.         break;
  529.      case LEFT_ARROW:
  530.      case LEFT_ARROW_2:
  531.         if (--curval < 0)
  532.            curval = llen - 1;
  533.         break;
  534.      case F5:
  535.         curval = initval;
  536.         break;
  537.      default:
  538.             if (nonalpha(curkey)) {
  539.            if (checkkey && (ret = (*checkkey)(curkey)) != 0)
  540.           goto inpfldl_end;
  541.            break;                     /* non alphanum char */
  542.            }
  543.         j = curval;
  544.         for (i = 0; i < llen; ++i) {
  545.            if (++j >= llen)
  546.           j = 0;
  547.            if ((*list[j] & 0xdf) == (curkey & 0xdf)) {
  548.           curval = j;
  549.           break;
  550.           }
  551.            }
  552.      }
  553.       }
  554. inpfldl_end:
  555.    strcpy(fld,list[curval]);
  556.    lookatmouse = savelookatmouse;
  557.    return(ret);
  558. }
  559.  
  560.  
  561. /* --------------------------------------------------------------------- */
  562.  
  563. /* MCP 7-7-91, This is static code, but not called anywhere */
  564. #ifdef DELETE_UNUSED_CODE
  565.  
  566. /* compare for sort of type table */
  567. static int compare(const VOIDPTR i, const VOIDPTR j)
  568. {
  569.    return(strcmp(fractalspecific[(int)*((BYTE*)i)].name,
  570.            fractalspecific[(int)*((BYTE*)j)].name));
  571. }
  572.  
  573. /* --------------------------------------------------------------------- */
  574.  
  575. static void clear_line(int row, int start, int stop, int color) /* clear part of a line */
  576. {
  577.    int col;
  578.    for(col=start;col<= stop;col++)
  579.       putstring(row,col,color," ");
  580. }
  581.  
  582. #endif
  583.  
  584. /* --------------------------------------------------------------------- */
  585.  
  586. int get_fracttype()        /* prompt for and select fractal type */
  587. {
  588.    int done,i,oldfractype,t;
  589.    done = -1;
  590.    oldfractype = fractype;
  591.    for(;;) {
  592.       if ((t = select_fracttype(fractype)) < 0)
  593.      break;
  594.       if ((i = select_type_params(t, fractype)) == 0) { /* ok, all done */
  595.      done = 0;
  596.      break;
  597.      }
  598.       if (i > 0) /* can't return to prior image anymore */
  599.      done = 1;
  600.       }
  601.    if (done < 0)
  602.       fractype = oldfractype;
  603.    curfractalspecific = &fractalspecific[fractype];
  604.    return(done);
  605. }
  606.  
  607. struct FT_CHOICE {
  608.       char name[15];
  609.       int  num;
  610.       };
  611. static struct FT_CHOICE far **ft_choices; /* for sel_fractype_help subrtn */
  612.  
  613. static int select_fracttype(int t) /* subrtn of get_fracttype, separated */
  614.                    /* so that storage gets freed up     */
  615. {
  616.    static FCODE head1[] = {"Select a Fractal Type"};
  617.    static FCODE head2[] = {"Select Orbit Algorithm for Julibrot"};
  618.    static FCODE o_instr[] = {"Press F2 for a description of the highlighted type"};
  619.    char instr[sizeof(o_instr)];
  620.    char head[40];
  621.    int oldhelpmode;
  622.    int numtypes, done;
  623.    int i, j;
  624. #define MAXFTYPES 200
  625.    char tname[40];
  626.    struct FT_CHOICE far *choices[MAXFTYPES];
  627.    int attributes[MAXFTYPES];
  628.  
  629.    /* steal existing array for "choices" */
  630.    choices[0] = (struct FT_CHOICE far *)boxy;
  631.    attributes[0] = 1;
  632.    for (i = 1; i < MAXFTYPES; ++i) {
  633.       choices[i] = choices[i-1] + 1;
  634.       attributes[i] = 1;
  635.       }
  636.    ft_choices = &choices[0];
  637.  
  638.    /* setup context sensitive help */
  639.    oldhelpmode = helpmode;
  640.    helpmode = HELPFRACTALS;
  641.    far_strcpy(instr,o_instr);
  642.    if(julibrot)
  643.       far_strcpy(head,head2);
  644.    else
  645.       far_strcpy(head,head1);    
  646.    if (t == IFS3D) t = IFS;
  647.    i = j = -1;
  648.    while(fractalspecific[++i].name) {
  649.       if(julibrot)
  650.     if (!((fractalspecific[i].flags & OKJB) && *fractalspecific[i].name != '*'))
  651.        continue;
  652.       if (fractalspecific[i].name[0] == '*')
  653.      continue;
  654.       far_strcpy(choices[++j]->name,fractalspecific[i].name);
  655.       choices[j]->name[14] = 0; /* safety */
  656.       choices[j]->num = i;    /* remember where the real item is */
  657.       }
  658.    numtypes = j + 1;
  659.    shell_sort(choices,numtypes,sizeof(char far *),lccompare); /* sort list */
  660.    j = 0;
  661.    for (i = 0; i < numtypes; ++i) /* find starting choice in sorted list */
  662.       if (choices[i]->num == t || choices[i]->num == fractalspecific[t].tofloat)
  663.      j = i;
  664.  
  665.    tname[0] = 0;
  666.    done = fullscreen_choice(CHOICEHELP+8,head,NULL,instr,numtypes,
  667.          (char far *far*)choices,attributes,0,0,0,j,NULL,tname,NULL,sel_fractype_help);
  668.    if (done >= 0)
  669.       done = choices[done]->num;
  670.    helpmode = oldhelpmode;
  671.    return(done);
  672. }
  673.  
  674. static int sel_fractype_help(int curkey,int choice)
  675. {
  676.    int oldhelpmode;
  677.    if (curkey == F2) {
  678.       oldhelpmode = helpmode;
  679.       helpmode = fractalspecific[(*(ft_choices+choice))->num].helptext;
  680.       help(0);
  681.       helpmode = oldhelpmode;
  682.       }
  683.    return(0);
  684. }
  685.  
  686. int select_type_params(    /* prompt for new fractal type parameters */
  687.     int newfractype,    /* new fractal type */
  688.     int oldfractype     /* previous fractal type */
  689.     )
  690. {
  691.    int ret,oldhelpmode;
  692.  
  693.    oldhelpmode = helpmode;
  694. sel_type_restart:
  695.    ret = 0;
  696.    fractype = newfractype;
  697.    curfractalspecific = &fractalspecific[fractype];
  698.  
  699.    if (fractype == LSYSTEM) {
  700.       helpmode = HT_LSYS;
  701.       if (get_file_entry(GETLSYS,"L-System",lsysmask,LFileName,LName) < 0) {
  702.      ret = 1;
  703.      goto sel_type_exit;
  704.      }
  705.       }
  706.    if (fractype == FORMULA || fractype == FFORMULA) {
  707.       helpmode = HT_FORMULA;
  708.       if (get_file_entry(GETFORMULA,"Formula",formmask,FormFileName,FormName) < 0) {
  709.      ret = 1;
  710.      goto sel_type_exit;
  711.      }
  712.       }
  713.    if (fractype == IFS || fractype == IFS3D) {
  714.       helpmode = HT_IFS;
  715.       if (get_file_entry(GETIFS,"IFS",ifsmask,IFSFileName,IFSName) < 0) {
  716.     ret = 1;
  717.     goto sel_type_exit;
  718.     }
  719.       }
  720.  
  721. /* Added the following to accommodate fn bifurcations.  JCO 7/2/92 */
  722.    if(((fractype == BIFURCATION) || (fractype == LBIFURCATION)) &&
  723.      !((oldfractype == BIFURCATION) || (oldfractype == LBIFURCATION)))
  724.         set_trig_array(0,s_ident);
  725.    if(((fractype == BIFSTEWART) || (fractype == LBIFSTEWART)) &&
  726.      !((oldfractype == BIFSTEWART) || (oldfractype == LBIFSTEWART)))
  727.         set_trig_array(0,s_ident);
  728.    if(((fractype == BIFLAMBDA) || (fractype == LBIFLAMBDA)) &&
  729.      !((oldfractype == BIFLAMBDA) || (oldfractype == LBIFLAMBDA)))
  730.         set_trig_array(0,s_ident);
  731.    if(((fractype == BIFEQSINPI) || (fractype == LBIFEQSINPI)) &&
  732.      !((oldfractype == BIFEQSINPI) || (oldfractype == LBIFEQSINPI)))
  733.         set_trig_array(0,s_sin);
  734.    if(((fractype == BIFADSINPI) || (fractype == LBIFADSINPI)) &&
  735.      !((oldfractype == BIFADSINPI) || (oldfractype == LBIFADSINPI)))
  736.         set_trig_array(0,s_sin);
  737.  
  738.    set_default_parms();
  739.  
  740.    if (get_fract_params(0) < 0)
  741.       if (fractype == FORMULA || fractype == FFORMULA ||
  742.           fractype == IFS || fractype == IFS3D ||
  743.           fractype == LSYSTEM)
  744.          goto sel_type_restart;
  745.       else
  746.          ret = 1;
  747.    else {
  748.       if (newfractype != oldfractype) {
  749.      invert = 0;
  750.      inversion[0] = inversion[1] = inversion[2] = 0;
  751.      }
  752.       }
  753.  
  754. sel_type_exit:
  755.    helpmode = oldhelpmode;
  756.    return(ret);
  757.  
  758. }
  759.  
  760. void set_default_parms()
  761. {
  762.    int i,extra;
  763.    xxmin = curfractalspecific->xmin;
  764.    xxmax = curfractalspecific->xmax;
  765.    yymin = curfractalspecific->ymin;
  766.    yymax = curfractalspecific->ymax;
  767.    xx3rd = xxmin;
  768.    yy3rd = yymin;
  769.    
  770.    if (viewcrop && finalaspectratio != screenaspect)
  771.       aspectratio_crop(screenaspect,finalaspectratio);
  772.    for (i = 0; i < 4; i++) {
  773.       param[i] = curfractalspecific->paramvalue[i];
  774.       if (fractype != CELLULAR && fractype != FROTH && fractype != FROTHFP)
  775.          roundfloatd(¶m[i]);   /* don't round cellular or frothybasin */
  776.    }
  777.    if((extra=find_extra_param(fractype)) > -1)
  778.       for(i=0;i<MAXPARAMS-4;i++) 
  779.          param[i+4] = moreparams[extra].paramvalue[i];
  780.    if(debugflag != 3200)
  781.       bf_math = 0;
  782.    else if(bf_math)
  783.       fractal_floattobf();
  784. }
  785.  
  786. #define MAXFRACTALS 25 
  787.  
  788. int build_fractal_list(int fractals[], int *last_val, char *nameptr[])
  789. {
  790.     int numfractals,i;
  791.  
  792.     numfractals = 0;
  793.     for (i = 0; i < num_fractal_types; i++)
  794.     {
  795.     if ((fractalspecific[i].flags & OKJB) && *fractalspecific[i].name != '*')
  796.     {
  797.         fractals[numfractals] = i;
  798.         if (i == neworbittype || i == fractalspecific[neworbittype].tofloat)
  799.         *last_val = numfractals;
  800.         nameptr[numfractals] = fractalspecific[i].name;
  801.         numfractals++;
  802.         if (numfractals >= MAXFRACTALS)
  803.         break;
  804.     }
  805.     }
  806.     return (numfractals);
  807. }
  808.  
  809. static FCODE v0a[] = {"From cx (real part)"};
  810. static FCODE v1a[] = {"From cy (imaginary part)"};
  811. static FCODE v2a[] = {"To   cx (real part)"};
  812. static FCODE v3a[] = {"To   cy (imaginary part)"};
  813.  
  814. /* 4D Mandelbrot */
  815. static FCODE v0b[] = {"From cj (3rd dim)"};
  816. static FCODE v1b[] = {"From ck (4th dim)"};
  817. static FCODE v2b[] = {"To   cj (3rd dim)"};
  818. static FCODE v3b[] = {"To   ck (4th dim)"};
  819.  
  820. /* 4D Julia */
  821. static FCODE v0c[] = {"From zj (3rd dim)"};
  822. static FCODE v1c[] = {"From zk (4th dim)"};
  823. static FCODE v2c[] = {"To   zj (3rd dim)"};
  824. static FCODE v3c[] = {"To   zk (4th dim)"};
  825.  
  826. static FCODE v4[] = {"Number of z pixels"};
  827. static FCODE v5[] = {"Location of z origin"};
  828. static FCODE v6[] = {"Depth of z"};
  829. static FCODE v7[] = {"Screen height"};
  830. static FCODE v8[] = {"Screen width"};
  831. static FCODE v9[] = {"Distance to Screen"};
  832. static FCODE v10[] = {"Distance between eyes"};
  833. static FCODE v11[] = {"3D Mode"};
  834. char *juli3Doptions[] = {"monocular","lefteye","righteye","red-blue"};
  835.  
  836. /* JIIM */
  837. #ifdef RANDOM_RUN
  838. static FCODE JIIMstr1[] = "Breadth first, Depth first, Random Walk, Random Run?";
  839. char *JIIMmethod[] = {"breadth", "depth", "walk", "run"};
  840. #else
  841. static FCODE JIIMstr1[] = "Breadth first, Depth first, Random Walk";
  842. char *JIIMmethod[] = {"breadth", "depth", "walk"};
  843. #endif
  844. static FCODE JIIMstr2[] = "Left first or Right first?";
  845. char *JIIMleftright[] = {"left", "right"};
  846.  
  847. /* --------------------------------------------------------------------- */
  848. int get_fract_params(int caller)    /* prompt for type-specific parms */
  849. {
  850.    char far *v0 = v0a;
  851.    char far *v1 = v1a;
  852.    char far *v2 = v2a;
  853.    char far *v3 = v3a;
  854.    char *juliorbitname = NULL;
  855.    int i,j,k;
  856.    int curtype,numparams,numtrig;
  857.    struct fullscreenvalues paramvalues[30];
  858.    char far *choices[30];
  859.    long oldbailout = 0L;
  860.    int promptnum;
  861.    char msg[120];
  862.    char *typename, *tmpptr;
  863.    char bailoutmsg[50];
  864.    int ret = 0;
  865.    int oldhelpmode;
  866.    static FCODE t1[] = {"First Function"};
  867.    static FCODE t2[] = {"Second Function"};
  868.    static FCODE t3[] = {"Third Function"};
  869.    static FCODE t4[] = {"Fourth Function"};
  870.    static FCODE *trg[] = {t1, t2, t3, t4};
  871.    char *filename,*entryname;
  872.    FILE *entryfile;
  873.    char *trignameptr[25];
  874. #ifdef XFRACT
  875.    static /* Can't initialize aggregates on the stack */
  876. #endif
  877.    char *bailnameptr[] = {s_mod,s_real,s_imag,s_or,s_and};
  878.    struct fractalspecificstuff far *jborbit = NULL;
  879.    struct fractalspecificstuff far *savespecific;
  880.    int firstparm =0;
  881.    int lastparm  = MAXPARAMS;
  882.    double oldparam[MAXPARAMS];
  883.    oldbailout = bailout;
  884.    if(fractype==JULIBROT || fractype==JULIBROTFP)
  885.       julibrot = 1;
  886.    else
  887.       julibrot = 0;
  888.    curtype = fractype;
  889.    if (curfractalspecific->name[0] == '*'
  890.      && (i = curfractalspecific->tofloat) != NOFRACTAL  /* FIXED BUG HERE!! */
  891.      && fractalspecific[i].name[0] != '*')
  892.       curtype = i;
  893.    curfractalspecific = &fractalspecific[curtype];
  894. #if 0
  895.    if (curtype == IFS || curtype == IFS3D) {
  896.       ret = ((caller) ? edit_ifs_params() : 0);
  897.       goto gfp_exit;
  898.       }
  899. #endif
  900.    tstack[0] = 0;
  901.    if ((i = curfractalspecific->helpformula) < -1) {
  902.       if (i == -2) { /* special for formula */
  903.      filename = FormFileName;
  904.      entryname = FormName;
  905.      }
  906.       else {     /* -3, special for lsystem */
  907.      filename = LFileName;
  908.      entryname = LName;
  909.      }
  910.       if (find_file_item(filename,entryname,&entryfile) == 0) {
  911.      load_entry_text(entryfile,tstack,16);
  912.      fclose(entryfile);
  913.      if(fractype == FORMULA || fractype == FFORMULA)
  914.        RunForm(entryname); /* no error check, should be okay, from above */
  915.      }
  916.       }
  917.    else if (i >= 0) {
  918.       int c,lines;
  919.       read_help_topic(i,0,2000,tstack); /* need error handling here ?? */
  920.       tstack[2000-i] = 0;
  921.       i = j = lines = 0; k = 1;
  922.       while ((c = tstack[i++]) != 0) {
  923.      /* stop at ctl, blank, or line with col 1 nonblank, max 16 lines */
  924.      if (k && c == ' ' && ++k <= 5) { } /* skip 4 blanks at start of line */
  925.      else {
  926.         if (c == '\n') {
  927.            if (k) break; /* blank line */
  928.            if (++lines >= 16) break;
  929.            k = 1;
  930.            }
  931.         else if (c < 16) /* a special help format control char */
  932.            break;
  933.         else {
  934.            if (k == 1) /* line starts in column 1 */
  935.           break;
  936.            k = 0;
  937.            }
  938.         tstack[j++] = (char)c;
  939.         }
  940.      }
  941.       while (--j >= 0 && tstack[j] == '\n') { }
  942.       tstack[j+1] = 0;
  943.       }
  944. gfp_top:   
  945.    promptnum = 0;
  946.    if (julibrot)
  947.    {
  948.       i = select_fracttype(neworbittype);
  949.       if (i < 0) 
  950.       {
  951.          if (ret == 0)
  952.             ret = -1;
  953.          julibrot = 0;
  954.          goto gfp_exit;
  955.       }
  956.       else
  957.          neworbittype = i;
  958.       jborbit = &fractalspecific[neworbittype];
  959.       juliorbitname = jborbit->name;
  960.    }
  961.  
  962.    if(fractype == FORMULA || fractype == FFORMULA) {
  963.       if(uses_p1)  /* set first parameter */
  964.          firstparm = 0;
  965.       else if(uses_p2)
  966.          firstparm = 2;
  967.       else
  968.          firstparm = 4; /* uses_p3 or no parameter */
  969.  
  970.       if(uses_p3)  /* set last parameter */
  971.          lastparm = 6;
  972.       else if(uses_p2)
  973.          lastparm = 4;
  974.       else
  975.          lastparm = 2; /* uses_p1 or no parameter */
  976.    }
  977.  
  978.    promptnum = 0;
  979.  
  980.    savespecific = curfractalspecific;
  981.    if(julibrot)
  982.    {
  983.       curfractalspecific = jborbit;
  984.       firstparm = 2; /* in most case Julibrot does not need first two parms */
  985.       if(neworbittype == QUATJULFP     ||   /* all parameters needed */ 
  986.          neworbittype == HYPERCMPLXJFP)
  987.       {
  988.          firstparm = 0;
  989.          lastparm = 4;
  990.       }    
  991.       if(neworbittype == QUATFP        ||   /* no parameters needed */
  992.          neworbittype == HYPERCMPLXFP)
  993.          firstparm = 4; 
  994.    }   
  995.    numparams = 0;
  996.    
  997.    for (i = firstparm; i < lastparm; i++) 
  998.    {
  999.       char tmpbuf[30];
  1000.       char *parm;
  1001.       if ((parm=typehasparm(julibrot?neworbittype:fractype,i))==NULL)
  1002.          break;
  1003.       numparams++;
  1004.       choices[promptnum] = parm;
  1005.       paramvalues[promptnum].type = 'd';
  1006.    
  1007.       if (choices[promptnum][0] == '+') 
  1008.       {
  1009.          choices[promptnum]++;
  1010.          paramvalues[promptnum].type = 'D';
  1011.       }
  1012.       else if (choices[promptnum][0] == '#') 
  1013.          choices[promptnum]++;
  1014.       sprintf(tmpbuf,"%.17g",param[i]);
  1015.       paramvalues[promptnum].uval.dval = atof(tmpbuf);
  1016.       oldparam[i] = paramvalues[promptnum++].uval.dval;
  1017.    }
  1018.  
  1019.    numtrig = (curfractalspecific->flags >> 6) & 7;
  1020.    if(curtype==FORMULA || curtype==FFORMULA ) {
  1021.       numtrig = maxfn;
  1022.       }
  1023.  
  1024.    if ((i = numtrigfn) > 27) i = 27;
  1025.    while (--i >= 0)
  1026.       trignameptr[i] = trigfn[i].name;
  1027.    for (i = 0; i < numtrig; i++) {
  1028.       paramvalues[promptnum].type = 'l';
  1029.       paramvalues[promptnum].uval.ch.val  = trigndx[i];
  1030.       paramvalues[promptnum].uval.ch.llen = numtrigfn;
  1031.       paramvalues[promptnum].uval.ch.vlen = 6;
  1032.       paramvalues[promptnum].uval.ch.list = trignameptr;
  1033.       choices[promptnum++] = (char far *)trg[i];
  1034.       }
  1035.    if (*(typename = curfractalspecific->name) == '*')
  1036.         ++typename;
  1037.  
  1038.    i = curfractalspecific->orbit_bailout;
  1039.  
  1040.    if( i != 0 && curfractalspecific->calctype == StandardFractal &&
  1041.        (curfractalspecific->flags & BAILTEST) &&
  1042.        potparam[0] == 0.0 && potparam[2] == 0.0 ) {
  1043.         static FCODE bailteststr[] = {"Bailout Test (mod, real, imag, or, and)"};
  1044.       paramvalues[promptnum].type = 'l';
  1045.       paramvalues[promptnum].uval.ch.val  = (int)bailoutest;
  1046.       paramvalues[promptnum].uval.ch.llen = 5;
  1047.       paramvalues[promptnum].uval.ch.vlen = 6;
  1048.       paramvalues[promptnum].uval.ch.list = bailnameptr;
  1049.       choices[promptnum++] = bailteststr;
  1050.    }
  1051.  
  1052.    if (i)
  1053.       if (potparam[0] != 0.0 && potparam[2] != 0.0) 
  1054.       {
  1055.         static FCODE bailpotstr[] = {"Bailout: continuous potential (Y screen) value in use"};
  1056.      paramvalues[promptnum].type = '*';
  1057.      choices[promptnum++] = bailpotstr;
  1058.       }
  1059.       else 
  1060.       {
  1061.          static FCODE bailoutstr[] = {"Bailout value (0 means use default)"};
  1062.      choices[promptnum] = bailoutstr;
  1063.      paramvalues[promptnum].type = 'L';
  1064.      paramvalues[promptnum++].uval.Lval = (oldbailout = bailout);
  1065.      paramvalues[promptnum].type = '*';
  1066.      tmpptr = typename;
  1067.      if (usr_biomorph != -1) 
  1068.      {
  1069.         i = 100;
  1070.         tmpptr = "biomorph";
  1071.      }
  1072.      sprintf(bailoutmsg,"    (%s default is %d)",tmpptr,i);
  1073.      choices[promptnum++] = bailoutmsg;
  1074.       }
  1075.    if (julibrot)
  1076.    {
  1077.       switch(neworbittype)
  1078.       {
  1079.       case QUATFP:
  1080.       case HYPERCMPLXFP:
  1081.           v0 = v0b; v1 = v1b; v2 = v2b; v3 = v3b;
  1082.           break;
  1083.       case QUATJULFP:
  1084.       case HYPERCMPLXJFP:
  1085.           v0 = v0c; v1 = v1c; v2 = v2c; v3 = v3c;
  1086.           break;
  1087.       default:
  1088.           v0 = v0a; v1 = v1a; v2 = v2a; v3 = v3a;
  1089.          break;
  1090.       }
  1091.  
  1092.       curfractalspecific = savespecific;
  1093.       paramvalues[promptnum].uval.dval = mxmaxfp;
  1094.       paramvalues[promptnum].type = 'f';
  1095.       choices[promptnum++] = v0;
  1096.       paramvalues[promptnum].uval.dval = mymaxfp;
  1097.       paramvalues[promptnum].type = 'f';
  1098.       choices[promptnum++] = v1;
  1099.       paramvalues[promptnum].uval.dval = mxminfp;
  1100.       paramvalues[promptnum].type = 'f';
  1101.       choices[promptnum++] = v2;
  1102.       paramvalues[promptnum].uval.dval = myminfp;
  1103.       paramvalues[promptnum].type = 'f';
  1104.       choices[promptnum++] = v3;
  1105.       paramvalues[promptnum].uval.ival = zdots;
  1106.       paramvalues[promptnum].type = 'i';
  1107.       choices[promptnum++] = v4;
  1108.  
  1109.       paramvalues[promptnum].type = 'l';
  1110.       paramvalues[promptnum].uval.ch.val  = juli3Dmode;
  1111.       paramvalues[promptnum].uval.ch.llen = 4;
  1112.       paramvalues[promptnum].uval.ch.vlen = 9;
  1113.       paramvalues[promptnum].uval.ch.list = juli3Doptions;
  1114.       choices[promptnum++] = v11;
  1115.  
  1116.       paramvalues[promptnum].uval.dval = eyesfp;
  1117.       paramvalues[promptnum].type = 'f';
  1118.       choices[promptnum++] = v10;
  1119.       paramvalues[promptnum].uval.dval = originfp;
  1120.       paramvalues[promptnum].type = 'f';
  1121.       choices[promptnum++] = v5;
  1122.       paramvalues[promptnum].uval.dval = depthfp;
  1123.       paramvalues[promptnum].type = 'f';
  1124.       choices[promptnum++] = v6;
  1125.       paramvalues[promptnum].uval.dval = heightfp;
  1126.       paramvalues[promptnum].type = 'f';
  1127.       choices[promptnum++] = v7;
  1128.       paramvalues[promptnum].uval.dval = widthfp;
  1129.       paramvalues[promptnum].type = 'f';
  1130.       choices[promptnum++] = v8;
  1131.       paramvalues[promptnum].uval.dval = distfp;
  1132.       paramvalues[promptnum].type = 'f';
  1133.       choices[promptnum++] = v9;
  1134.    }
  1135.  
  1136.    if (curtype == INVERSEJULIA || curtype == INVERSEJULIAFP)
  1137.    {
  1138.       choices[promptnum] = JIIMstr1;
  1139.       paramvalues[promptnum].type = 'l';
  1140.       paramvalues[promptnum].uval.ch.list = JIIMmethod;
  1141.       paramvalues[promptnum].uval.ch.vlen = 7;
  1142. #ifdef RANDOM_RUN
  1143.       paramvalues[promptnum].uval.ch.llen = 4;
  1144. #else
  1145.       paramvalues[promptnum].uval.ch.llen = 3; /* disable random run */
  1146. #endif
  1147.       paramvalues[promptnum++].uval.ch.val  = major_method;
  1148.  
  1149.       choices[promptnum] = JIIMstr2;
  1150.       paramvalues[promptnum].type = 'l';
  1151.       paramvalues[promptnum].uval.ch.list = JIIMleftright;
  1152.       paramvalues[promptnum].uval.ch.vlen = 5;
  1153.       paramvalues[promptnum].uval.ch.llen = 2;
  1154.       paramvalues[promptnum++].uval.ch.val  = minor_method;
  1155.    }
  1156.  
  1157.    if (caller                /* <z> command ? */
  1158. /*      && (display3d > 0 || promptnum == 0)) */
  1159.       && (display3d > 0))
  1160.       {
  1161.        static FCODE msg[]={"Current type has no type-specific parameters"};
  1162.        stopmsg(20,msg);
  1163.        goto gfp_exit;
  1164.        }
  1165.    if(julibrot)
  1166.       sprintf(msg,"Julibrot Parameters (orbit= %s)",juliorbitname);
  1167.    else
  1168.       sprintf(msg,"Parameters for fractal type %s",typename);
  1169.    far_strcat(msg,"\n(Press F6 for corner parameters)");
  1170.    for(;;)
  1171.    {
  1172.       oldhelpmode = helpmode;
  1173.       helpmode = curfractalspecific->helptext;
  1174.       i = fullscreen_prompt(msg,promptnum,choices,paramvalues,0x40,tstack);
  1175.       helpmode = oldhelpmode;
  1176.       if (i < 0) 
  1177.       {
  1178.          if(julibrot)
  1179.            goto gfp_top;
  1180.      if (ret == 0)
  1181.         ret = -1;
  1182.      goto gfp_exit;
  1183.       }
  1184.       if (i != F6) 
  1185.          break;
  1186.       if (get_corners() > 0)
  1187.      ret = 1;
  1188.      }
  1189.      promptnum = 0;
  1190.      for ( i = firstparm; i < numparams+firstparm; i++) 
  1191.      {
  1192.         if (oldparam[i] != paramvalues[promptnum].uval.dval) 
  1193.         {
  1194.            param[i] = paramvalues[promptnum].uval.dval;
  1195.           ret = 1;
  1196.         }
  1197.         ++promptnum;
  1198.     }
  1199.  
  1200.    for ( i = 0; i < numtrig; i++) 
  1201.    {
  1202.       if (paramvalues[promptnum].uval.ch.val != (int)trigndx[i]) 
  1203.       {
  1204.      set_trig_array(i,trigfn[paramvalues[promptnum].uval.ch.val].name);
  1205.      ret = 1;
  1206.       }
  1207.       ++promptnum;
  1208.    }
  1209.  
  1210.    if(julibrot)
  1211.    {
  1212.       savespecific = curfractalspecific;
  1213.       curfractalspecific = jborbit;
  1214.    }   
  1215.  
  1216.    i = curfractalspecific->orbit_bailout;
  1217.  
  1218.    if( i != 0 && curfractalspecific->calctype == StandardFractal &&
  1219.        (curfractalspecific->flags & BAILTEST) &&
  1220.        potparam[0] == 0.0 && potparam[2] == 0.0 ) {
  1221.       if (paramvalues[promptnum].uval.ch.val != (int)bailoutest) {
  1222.         bailoutest = (enum bailouts)paramvalues[promptnum].uval.ch.val;
  1223.         ret = 1;
  1224.       }
  1225.       promptnum++;
  1226.    }
  1227.    else
  1228.       bailoutest = Mod;
  1229.    setbailoutformula(bailoutest);
  1230.  
  1231.    if (i)
  1232.       if (potparam[0] != 0.0 && potparam[2] != 0.0) 
  1233.      promptnum++;
  1234.       else 
  1235.       {
  1236.          bailout = paramvalues[promptnum++].uval.Lval;
  1237.          if (bailout != 0 && (bailout < 1 || bailout > 2100000000L))
  1238.         bailout = oldbailout;
  1239.          if (bailout != oldbailout)
  1240.         ret = 1;
  1241.      promptnum++;
  1242.       }
  1243.  
  1244.      if (julibrot)
  1245.      {
  1246.     mxmaxfp    = paramvalues[promptnum++].uval.dval;
  1247.     mymaxfp    = paramvalues[promptnum++].uval.dval;
  1248.     mxminfp    = paramvalues[promptnum++].uval.dval;
  1249.     myminfp    = paramvalues[promptnum++].uval.dval;
  1250.     zdots      = paramvalues[promptnum++].uval.ival;
  1251.         juli3Dmode = paramvalues[promptnum++].uval.ch.val;
  1252.     eyesfp     = (float)paramvalues[promptnum++].uval.dval;
  1253.     originfp   = (float)paramvalues[promptnum++].uval.dval;
  1254.     depthfp    = (float)paramvalues[promptnum++].uval.dval;
  1255.     heightfp   = (float)paramvalues[promptnum++].uval.dval;
  1256.     widthfp    = (float)paramvalues[promptnum++].uval.dval;
  1257.     distfp     = (float)paramvalues[promptnum++].uval.dval;
  1258.         ret = 1;  /* force new calc since not resumable anyway */
  1259.      }
  1260.       if (curtype == INVERSEJULIA || curtype == INVERSEJULIAFP)
  1261.       {
  1262.      if (paramvalues[promptnum].uval.ch.val != major_method ||
  1263.          paramvalues[promptnum+1].uval.ch.val != minor_method)
  1264.         ret = 1;
  1265.      major_method = (enum Major)paramvalues[promptnum  ].uval.ch.val;
  1266.      minor_method = (enum Minor)paramvalues[promptnum+1].uval.ch.val;
  1267.       }
  1268.  
  1269. gfp_exit:
  1270.    curfractalspecific = &fractalspecific[fractype];
  1271.    return(ret);
  1272. }
  1273.  
  1274. int find_extra_param(int type)
  1275. {
  1276.    int i,ret,curtyp;
  1277.    ret = -1;
  1278.    i= -1;
  1279.  
  1280.    if(fractalspecific[type].flags&MORE)
  1281.    {
  1282.       while((curtyp=moreparams[++i].type) != type && curtyp != -1);
  1283.       if(curtyp == type)
  1284.         ret = i;
  1285.    }  
  1286.    return(ret);
  1287. }     
  1288.  
  1289. int check_orbit_name(char *orbitname)
  1290. {
  1291.    int i, numtypes, bad;
  1292.    char *nameptr[MAXFRACTALS];
  1293.    int fractals[MAXFRACTALS];
  1294.    int last_val;
  1295.  
  1296.    numtypes = build_fractal_list(fractals, &last_val, nameptr);
  1297.    bad = 1;
  1298.    for(i=0;i<numtypes;i++)
  1299.    {
  1300.       if(strcmp(orbitname,nameptr[i]) == 0)
  1301.       {
  1302.          neworbittype = fractals[i];
  1303.          bad = 0;
  1304.          break;
  1305.       }
  1306.    }
  1307.    return(bad);
  1308. }
  1309.  
  1310. /* --------------------------------------------------------------------- */
  1311.  
  1312. static FILE *gfe_file;
  1313.  
  1314. long get_file_entry(int type,char *title,char *fmask,
  1315.               char *filename,char *entryname)
  1316. {
  1317.    /* Formula, LSystem, etc type structure, select from file */
  1318.    /* containing definitions in the form    name { ... }     */
  1319.    int newfile,firsttry;
  1320.    long entry_pointer;
  1321.    newfile = 0;
  1322.    for(;;) {
  1323.       firsttry = 0;
  1324.       /* pb: binary mode used here - it is more work, but much faster, */
  1325.       /*     especially when ftell or fgetpos is used               */
  1326.       while (newfile || (gfe_file = fopen(filename, "rb")) == NULL) {
  1327.      char buf[60];
  1328.      newfile = 0;
  1329.      if (firsttry) {
  1330.         sprintf(temp1,s_cantfind, filename);
  1331.         stopmsg(0,temp1);
  1332.         }
  1333.      sprintf(buf,"Select %s File",title);
  1334.      if (getafilename(buf,fmask,filename) < 0)
  1335.         return -1;
  1336.         
  1337.      firsttry = 1; /* if around open loop again it is an error */
  1338.      }
  1339.       setvbuf(gfe_file,tstack,_IOFBF,4096); /* improves speed when file is big */
  1340.       newfile = 0;
  1341.       if ((entry_pointer = gfe_choose_entry(type,title,filename,entryname)) == -2) {
  1342.      newfile = 1; /* go to file list, */
  1343.      continue;    /* back to getafilename */
  1344.      }
  1345.       if (entry_pointer == -1)
  1346.      return -1;
  1347.       switch (type) {
  1348.      case GETFORMULA:
  1349.         if (RunForm(entryname) == 0) return 0;
  1350.         break;
  1351.      case GETLSYS:
  1352.         if (LLoad() == 0) return 0;
  1353.         break;
  1354.      case GETIFS:
  1355.         if (ifsload() == 0) {
  1356.            fractype = (ifs_type == 0) ? IFS : IFS3D;
  1357.            curfractalspecific = &fractalspecific[fractype];
  1358.            set_default_parms(); /* to correct them if 3d */
  1359.            return 0;
  1360.            }
  1361.         break;
  1362.      case GETPARM:
  1363.         return entry_pointer;
  1364.      }
  1365.       }
  1366. }
  1367.  
  1368. struct entryinfo {
  1369.    char name[ITEMNAMELEN+2];
  1370.    long point; /* points to the ( or the { following the name */
  1371.    };
  1372. static struct entryinfo far *far*gfe_choices; /* for format_getparm_line */
  1373. static char *gfe_title;
  1374.  
  1375. /* skip to next non-white space character and return it */
  1376. int skip_white_space(FILE *infile, long *file_offset)
  1377. {
  1378.    int c;
  1379.    do
  1380.    {
  1381.       c = getc(infile);
  1382.       (*file_offset)++; 
  1383.    }
  1384.    while (c == ' ' || c == '\t' || c == '\n' || c == '\r');
  1385.    return(c);
  1386. }
  1387.  
  1388. /* skip to end of line */
  1389. int skip_comment(FILE *infile, long *file_offset)
  1390. {
  1391.    int c;
  1392.    do
  1393.    {
  1394.       c = getc(infile);
  1395.       (*file_offset)++; 
  1396.    }
  1397.    while (c != '\n' && c != '\r' && c != EOF && c != '\032');
  1398.    return(c); 
  1399. }
  1400.  
  1401. #define MAXENTRIES 2000L
  1402. int scan_entries(FILE * infile, void far * ch, char *itemname)
  1403. {
  1404.    struct entryinfo far *far * choices;
  1405.    char buf[101];
  1406.    long name_offset, file_offset = -1;
  1407.    int numentries = 0;
  1408.  
  1409.    choices = (struct entryinfo far * far *) ch;
  1410.  
  1411.    for (;;)
  1412.    {                            /* scan the file for entry names */
  1413.       int c, len;
  1414.       if ((c = skip_white_space(infile, &file_offset)) == ';')
  1415.       {
  1416.          c = skip_comment(infile, &file_offset);
  1417.          if (c == EOF || c == '\032')
  1418.             break;
  1419.          continue;
  1420.       }
  1421.       name_offset = file_offset;
  1422.       /* next equiv roughly to fscanf(..,"%40[^* \n\r\t({\032]",buf) */
  1423.       len = 0; 
  1424.       while (c != ' ' && c != '\t' && c != '(' && c != ';'
  1425.            && c != '{' && c != '\n' && c != '\r' && c != EOF && c != '\032')
  1426.       {
  1427.          if (len < 40)
  1428.             buf[len++] = (char) c;
  1429.          c = getc(infile);
  1430.          ++file_offset;
  1431.       }
  1432.       buf[len] = 0;
  1433.       while (c != '{' && /* c != '\n' && c != '\r' && */  c != EOF && c != '\032')
  1434.       {
  1435.          if(c == ';')
  1436.             c = skip_comment(infile, &file_offset);
  1437.          else
  1438.          { 
  1439.             c = getc(infile);
  1440.             ++file_offset;
  1441.          }   
  1442.       }
  1443.       if (c == '{')
  1444.       {
  1445.          while (c != '}' && c != EOF && c != '\032')
  1446.          {
  1447.             if(c == ';')
  1448.                c = skip_comment(infile, &file_offset);
  1449.             else
  1450.             {
  1451.                c = getc(infile);
  1452.                ++file_offset;
  1453.             }   
  1454.          }
  1455.          if (c != '}')
  1456.             break;
  1457.          buf[ITEMNAMELEN] = 0;
  1458.          if (itemname != NULL)  /* looking for one entry */
  1459.          {
  1460.             if (stricmp(buf, itemname) == 0)
  1461.             {
  1462.                fseek(infile, name_offset, SEEK_SET);
  1463.                return (-1);
  1464.             }
  1465.          }
  1466.          else /* make a whole list of entries */
  1467.          {
  1468.             if (buf[0] != 0 && stricmp(buf, "comment") != 0)
  1469.             {
  1470.                far_strcpy(choices[numentries]->name, buf);
  1471.                choices[numentries]->point = name_offset;
  1472.                if (++numentries >= MAXENTRIES)
  1473.                {
  1474.                   sprintf(buf, "Too many entries in file, first %ld used", MAXENTRIES);
  1475.                   stopmsg(0, buf);
  1476.                   break;
  1477.                }
  1478.             }
  1479.          }
  1480.       }
  1481.       else if (c == EOF || c == '\032')
  1482.          break;
  1483.    }
  1484.    return (numentries);
  1485. }
  1486.  
  1487. static long gfe_choose_entry(int type,char *title,char *filename,char *entryname)
  1488. /* subrtn of get_file_entry, separated so that storage gets freed up */
  1489. {
  1490.    static FCODE o_instr[]={"Press F6 to select different file, F2 for details, F4 to toggle sort "};
  1491.    int numentries, i;
  1492.    char buf[101];
  1493.    struct entryinfo far * far *choices;
  1494.    int far *attributes;
  1495.    void (*formatitem)(int, char *);
  1496.    int boxwidth,boxdepth,colwidth;
  1497.    static int dosort = 1;
  1498.    int options = 8;
  1499.    char far *instr;   
  1500.    /* steal existing array for "choices" */
  1501.    choices = (struct entryinfo far *far*)MK_FP(extraseg,0);
  1502.    /* leave room for details F2 */  
  1503.    choices = choices + (2048/sizeof(struct entryinfo far *far*)); 
  1504.    choices[0] = (struct entryinfo far *)(choices + MAXENTRIES+1);
  1505.    attributes = (int far *)(choices[0] + MAXENTRIES+1);
  1506.    instr = (char far *)(attributes + MAXENTRIES +1);
  1507.    gfe_choices = &choices[0];
  1508.    gfe_title = title;
  1509. retry:
  1510.    attributes[0] = 1;
  1511.    for(i=1;i<MAXENTRIES+1;i++)
  1512.    {
  1513.       choices[i] = choices[i-1] + 1;
  1514.       attributes[i] = 1;
  1515.    }
  1516.  
  1517.    numentries = 0;
  1518.    helptitle(); /* to display a clue when file big and next is slow */
  1519.  
  1520.    numentries=scan_entries(gfe_file,choices,NULL);
  1521.    if (numentries == 0) {
  1522.       static FCODE msg[]={"File doesn't contain any valid entries"};
  1523.       stopmsg(0,msg);
  1524.       fclose(gfe_file);
  1525.       return -2; /* back to file list */
  1526.       }
  1527.    far_strcpy(instr,o_instr);
  1528.    if(dosort)
  1529.    {
  1530.       far_strcat(instr,"off");
  1531.       shell_sort((char far *)choices,numentries,sizeof(char far *),lccompare);
  1532.    }
  1533.    else
  1534.       far_strcat(instr,"on");
  1535.    
  1536.    strcpy(buf,entryname); /* preset to last choice made */
  1537.    sprintf(temp1,"%s Selection\nFile: %s",title,filename);
  1538.    formatitem = NULL;
  1539.    boxwidth = colwidth = boxdepth = 0;
  1540.    if (type == GETPARM) {
  1541.       formatitem = format_parmfile_line;
  1542.       boxwidth = 1;
  1543.       boxdepth = 16;
  1544.       colwidth = 76;
  1545.       }
  1546.    if(dosort)
  1547.       options = 8;
  1548.    else
  1549.       options = 8+32;   
  1550.    i = fullscreen_choice(options,temp1,NULL,instr,numentries,(char far*far*)choices,
  1551.                            attributes,boxwidth,boxdepth,colwidth,0,
  1552.                formatitem,buf,NULL,check_gfe_key);
  1553.    if (i == 0-F4)
  1554.    {
  1555.      rewind(gfe_file);
  1556.      dosort = 1-dosort;
  1557.      goto retry;
  1558.    }
  1559.    fclose(gfe_file);
  1560.    if (i < 0) {
  1561.       if (i == 0-F6)
  1562.      return -2; /* go back to file list */
  1563.       return -1;    /* cancel */
  1564.       }
  1565.    far_strcpy(entryname, choices[i]->name);
  1566.    return(choices[i]->point);
  1567. }
  1568.  
  1569.  
  1570. static int check_gfe_key(int curkey,int choice)
  1571. {
  1572.    char infhdg[60];
  1573.    char far *infbuf;
  1574.  
  1575.    if (curkey == F6)
  1576.       return 0-F6;
  1577.    if (curkey == F4)
  1578.       return 0-F4;
  1579.    if (curkey == F2) {
  1580.       infbuf = MK_FP(extraseg,0);
  1581.       fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET);
  1582.       load_entry_text(gfe_file,infbuf,16);
  1583.       strcpy(infhdg,gfe_title);
  1584.       strcat(infhdg," file entry:\n\n");
  1585.  /* ... instead, call help with buffer?  heading added */
  1586.       stackscreen();
  1587.       helptitle();
  1588.       setattr(1,0,C_GENERAL_MED,24*80);
  1589.       putstring(2,1,C_GENERAL_HI,infhdg);
  1590.       textcbase = 2; /* left margin is 2 */
  1591.       putstring(-1,0,C_GENERAL_MED,infbuf);
  1592.       {
  1593.       static FCODE msg[] = {"\n\n\nPress any key to return to selection list"};
  1594.       putstring(-1,0,C_GENERAL_LO,msg);
  1595.       }
  1596.       textcbase = 0;
  1597.       movecursor(25,80);
  1598.       getakeynohelp();
  1599.       unstackscreen();
  1600.       }
  1601.    return 0;
  1602. }
  1603.  
  1604. static void load_entry_text(FILE *entfile,char far *buf,int maxlines)
  1605. {
  1606.    int linect,linelen,c,comment=0;
  1607.    linect = linelen = 0;
  1608.    while ((c = fgetc(entfile)) != EOF && c != '\032') {
  1609.       if (c == ';')
  1610.          comment = 1;
  1611.       else if (c == '\n' || c == '\r')
  1612.          comment = 0;         
  1613.       if (c != '\r') {
  1614.      if (c == '\t') {
  1615.         while ((linelen % 8) != 7 && linelen < 75) { /* 76 wide max */
  1616.            *(buf++) = ' ';
  1617.            ++linelen;
  1618.            }
  1619.         c = ' ';
  1620.         }
  1621.      if (c == '\n') {
  1622.         if (++linect > maxlines) break;
  1623.         linelen = -1;
  1624.         }
  1625.      if (++linelen > 75) {
  1626.         if (linelen == 76) *(buf++) = '\021';
  1627.         }
  1628.      else
  1629.         *(buf++) = (char)c;
  1630.      if (comment == 0 && c == '}') break;
  1631.      }
  1632.       }
  1633.    *buf = 0;
  1634. }
  1635.  
  1636. static void format_parmfile_line(int choice,char *buf)
  1637. {
  1638.    int c,i;
  1639.    char line[80];
  1640.    fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET);
  1641.    while (getc(gfe_file) != '{') { }
  1642.    while ((c = getc(gfe_file)) == ' ' || c == '\t' || c == ';') { }
  1643.    i = 0;
  1644.    while (i < 56 && c != '\n' && c != '\r' && c != EOF && c != '\032') {
  1645.       line[i++] = (char)((c == '\t') ? ' ' : c);
  1646.       c = getc(gfe_file);
  1647.       }
  1648.    line[i] = 0;
  1649. #ifndef XFRACT   
  1650.    sprintf(buf,"%-20Fs%-56s",gfe_choices[choice]->name,line);
  1651. #else
  1652.    sprintf(buf,"%-20s%-56s",gfe_choices[choice]->name,line);
  1653. #endif
  1654. }
  1655.  
  1656. /* --------------------------------------------------------------------- */
  1657.  
  1658. int get_fract3d_params() /* prompt for 3D fractal parameters */
  1659. {
  1660.    int i,k,ret,oldhelpmode;
  1661.    static FCODE hdg[] = {"3D Parameters"};
  1662.    static FCODE p1[] = {"X-axis rotation in degrees"};
  1663.    static FCODE p2[] = {"Y-axis rotation in degrees"};
  1664.    static FCODE p3[] = {"Z-axis rotation in degrees"};
  1665.    static FCODE p4[] = {"Perspective distance [1 - 999, 0 for no persp]"};
  1666.    static FCODE p5[] = {"X shift with perspective (positive = right)"};
  1667.    static FCODE p6[] = {"Y shift with perspective (positive = up   )"};
  1668.    static FCODE p7[] = {"Stereo (R/B 3D)? (0=no,1=alternate,2=superimpose,3=photo)"};
  1669.    struct fullscreenvalues uvalues[20];
  1670.    char far *ifs3d_prompts[8];
  1671.  
  1672.    stackscreen();
  1673.    ifs3d_prompts[0] = p1;
  1674.    ifs3d_prompts[1] = p2;
  1675.    ifs3d_prompts[2] = p3;
  1676.    ifs3d_prompts[3] = p4;
  1677.    ifs3d_prompts[4] = p5;
  1678.    ifs3d_prompts[5] = p6;
  1679.    ifs3d_prompts[6] = p7;
  1680.    k = 0;
  1681.    uvalues[k].type = 'i';
  1682.    uvalues[k++].uval.ival = XROT;
  1683.    uvalues[k].type = 'i';
  1684.    uvalues[k++].uval.ival = YROT;
  1685.    uvalues[k].type = 'i';
  1686.    uvalues[k++].uval.ival = ZROT;
  1687.    uvalues[k].type = 'i';
  1688.    uvalues[k++].uval.ival = ZVIEWER;
  1689.    uvalues[k].type = 'i';
  1690.    uvalues[k++].uval.ival = XSHIFT;
  1691.    uvalues[k].type = 'i';
  1692.    uvalues[k++].uval.ival = YSHIFT;
  1693.    uvalues[k].type = 'i';
  1694.    uvalues[k++].uval.ival = glassestype;
  1695.  
  1696.    oldhelpmode = helpmode;
  1697.    helpmode = HELP3DFRACT;
  1698.    i = fullscreen_prompt(hdg,k,ifs3d_prompts,uvalues,0,NULL);
  1699.    helpmode = oldhelpmode;
  1700.    if (i < 0) {
  1701.       ret = -1;
  1702.       goto get_f3d_exit;
  1703.       }
  1704.  
  1705.    ret = k = 0;
  1706.    XROT    =  uvalues[k++].uval.ival;
  1707.    YROT    =  uvalues[k++].uval.ival;
  1708.    ZROT    =  uvalues[k++].uval.ival;
  1709.    ZVIEWER =  uvalues[k++].uval.ival;
  1710.    XSHIFT  =  uvalues[k++].uval.ival;
  1711.    YSHIFT  =  uvalues[k++].uval.ival;
  1712.    glassestype = uvalues[k++].uval.ival;
  1713.    if (glassestype < 0 || glassestype > 3) glassestype = 0;
  1714.    if (glassestype)
  1715.       if (get_funny_glasses_params() || check_mapfile())
  1716.      ret = -1;
  1717.  
  1718. get_f3d_exit:
  1719.    unstackscreen();
  1720.    return(ret);
  1721. }
  1722.  
  1723. /* --------------------------------------------------------------------- */
  1724. /* These macros streamline the "save near space" campaign */ 
  1725.  
  1726. #define LOADPROMPTS3D(X)     {\
  1727.    static FCODE tmp[] = { X };\
  1728.    prompts3d[++k]= tmp;\
  1729.    }
  1730.  
  1731. #define LOADPROMPTSCHOICES(X)     {\
  1732.    static FCODE tmp[] = { X };\
  1733.    choices[k++]= tmp;\
  1734.    }
  1735.    
  1736. int get_3d_params()    /* prompt for 3D parameters */
  1737. {
  1738.    static FCODE hdg[]={"3D Mode Selection"};
  1739.    static FCODE hdg1[]={"Select 3D Fill Type"};
  1740.    char far *choices[11];
  1741.    int attributes[21];
  1742.    int sphere;
  1743.    char far *s;
  1744.    static FCODE s1[] = {"              Sphere 3D Parameters\n\
  1745. Sphere is on its side; North pole to right\n\
  1746. Long. 180 is top, 0 is bottom; Lat. -90 is left, 90 is right"};
  1747.    static char s2[]={"              Planar 3D Parameters\n\
  1748. Pre-rotation X axis is screen top; Y axis is left side\n\
  1749. Pre-rotation Z axis is coming at you out of the screen!"};
  1750.    char far *prompts3d[21];
  1751.    struct fullscreenvalues uvalues[21];
  1752.    int i, k;
  1753.    int oldhelpmode;
  1754.  
  1755. #ifdef WINFRACT
  1756.      {
  1757.      extern int far wintext_textmode;
  1758.      if (wintext_textmode != 2)  /* are we in textmode? */
  1759.          return(0);              /* no - prompts are already handled */
  1760.      }
  1761. #endif
  1762. restart_1:
  1763.     if (Targa_Out && overlay3d)
  1764.         Targa_Overlay = 1;
  1765.  
  1766.    k= -1;
  1767.  
  1768.    LOADPROMPTS3D("Preview Mode?");
  1769.    uvalues[k].type = 'y';
  1770.    uvalues[k].uval.ch.val = preview;
  1771.  
  1772.    LOADPROMPTS3D("    Show Box?");
  1773.    uvalues[k].type = 'y';
  1774.    uvalues[k].uval.ch.val = showbox;
  1775.    
  1776.    LOADPROMPTS3D("Coarseness, preview/grid/ray (in y dir)");
  1777.    uvalues[k].type = 'i';
  1778.    uvalues[k].uval.ival = previewfactor;
  1779.  
  1780.    LOADPROMPTS3D("Spherical Projection?");
  1781.    uvalues[k].type = 'y';
  1782.    uvalues[k].uval.ch.val = sphere = SPHERE;
  1783.  
  1784.    LOADPROMPTS3D("Stereo (R/B 3D)? (0=no,1=alternate,2=superimpose,3=photo)");
  1785.    uvalues[k].type = 'i';
  1786.    uvalues[k].uval.ival = glassestype;
  1787.  
  1788.    LOADPROMPTS3D("Ray trace out? (0=No, 1=DKB/POVRay, 2=VIVID, 3=RAW,");
  1789.    uvalues[k].type = 'i';
  1790.    uvalues[k].uval.ival = RAY;
  1791.  
  1792.    LOADPROMPTS3D("                4=MTV, 5=RAYSHADE, 6=ACROSPIN, 7=DXF)");
  1793.    uvalues[k].type = '*';
  1794.  
  1795.    LOADPROMPTS3D("    Brief output?");
  1796.    uvalues[k].type = 'y';
  1797.    uvalues[k].uval.ch.val = BRIEF;
  1798.  
  1799.    check_writefile(ray_name,".ray");
  1800.    LOADPROMPTS3D("    Output File Name");
  1801.    uvalues[k].type = 's';
  1802.    strcpy(uvalues[k].uval.sval,ray_name);
  1803.  
  1804.    LOADPROMPTS3D("Targa output?");
  1805.    uvalues[k].type = 'y';
  1806.    uvalues[k].uval.ch.val = Targa_Out;
  1807.  
  1808.    LOADPROMPTS3D("Use grayscale value for depth? (if \"no\" uses color number)");
  1809.    uvalues[k].type = 'y';
  1810.    uvalues[k].uval.ch.val = grayflag;
  1811.  
  1812.    oldhelpmode = helpmode;
  1813.    helpmode = HELP3DMODE;
  1814.  
  1815.    k = fullscreen_prompt(hdg,k+1,prompts3d,uvalues,0,NULL);
  1816.    helpmode = oldhelpmode;
  1817.    if (k < 0) {
  1818.       return(-1);
  1819.       }
  1820.  
  1821.    k=0;
  1822.  
  1823.    preview = (char)uvalues[k++].uval.ch.val;
  1824.  
  1825.    showbox = (char)uvalues[k++].uval.ch.val;
  1826.  
  1827.    previewfactor  = uvalues[k++].uval.ival;
  1828.  
  1829.    sphere = uvalues[k++].uval.ch.val;
  1830.  
  1831.    glassestype = uvalues[k++].uval.ival;
  1832.  
  1833.    RAY = uvalues[k++].uval.ival;
  1834.    k++;
  1835.    {
  1836.       static FCODE msg[] = {
  1837. "DKB/POV-Ray output is obsolete but still works. See \"Ray Tracing Output\" in\n\
  1838. the online documentation."};
  1839.       if(RAY == 1)
  1840.          stopmsg(0,msg);
  1841.    }
  1842.    BRIEF = uvalues[k++].uval.ch.val;
  1843.  
  1844.    strcpy(ray_name,uvalues[k++].uval.sval);
  1845.  
  1846.    Targa_Out = uvalues[k++].uval.ch.val;
  1847.    grayflag  = (char)uvalues[k++].uval.ch.val;
  1848.  
  1849.    /* check ranges */
  1850.    if(previewfactor < 2)
  1851.       previewfactor = 2;
  1852.    if(previewfactor > 2000)
  1853.       previewfactor = 2000;
  1854.  
  1855.    if(sphere && !SPHERE)
  1856.    {
  1857.       SPHERE = TRUE;
  1858.       set_3d_defaults();
  1859.    }
  1860.    else if(!sphere && SPHERE)
  1861.    {
  1862.       SPHERE = FALSE;
  1863.       set_3d_defaults();
  1864.    }
  1865.  
  1866.    if(glassestype < 0)
  1867.       glassestype = 0;
  1868.    if(glassestype > 3)
  1869.       glassestype = 3;
  1870.    if(glassestype)
  1871.       whichimage = 1;
  1872.  
  1873.    if (RAY < 0)
  1874.       RAY = 0;
  1875.    if (RAY > 7)
  1876.       RAY = 7;
  1877.  
  1878.    if (!RAY)
  1879.    {
  1880.       k = 0;
  1881.       LOADPROMPTSCHOICES("make a surface grid");
  1882.       LOADPROMPTSCHOICES("just draw the points");
  1883.       LOADPROMPTSCHOICES("connect the dots (wire frame)");
  1884.       LOADPROMPTSCHOICES("surface fill (colors interpolated)");
  1885.       LOADPROMPTSCHOICES("surface fill (colors not interpolated)");
  1886.       LOADPROMPTSCHOICES("solid fill (bars up from \"ground\")");
  1887.       if(SPHERE)
  1888.       {
  1889.          LOADPROMPTSCHOICES("light source");
  1890.       }
  1891.       else
  1892.       {
  1893.          LOADPROMPTSCHOICES("light source before transformation");
  1894.          LOADPROMPTSCHOICES("light source after transformation");
  1895.       }
  1896.       for (i = 0; i < k; ++i)
  1897.      attributes[i] = 1;
  1898.       helpmode = HELP3DFILL;
  1899.       i = fullscreen_choice(CHOICEHELP,hdg1,NULL,NULL,k,(char far * far *)choices,attributes,
  1900.                   0,0,0,FILLTYPE+1,NULL,NULL,NULL,NULL);
  1901.       helpmode = oldhelpmode;
  1902.       if (i < 0)
  1903.      goto restart_1;
  1904.       FILLTYPE = i-1;
  1905.  
  1906.       if(glassestype)
  1907.       {
  1908.      if(get_funny_glasses_params())
  1909.             goto restart_1;
  1910.          }
  1911.          if (check_mapfile())
  1912.              goto restart_1;
  1913.       }
  1914.    restart_3:
  1915.  
  1916.    if(SPHERE)
  1917.    {
  1918.       k = -1;
  1919.       LOADPROMPTS3D("Longitude start (degrees)");
  1920.       LOADPROMPTS3D("Longitude stop  (degrees)");
  1921.       LOADPROMPTS3D("Latitude start  (degrees)");
  1922.       LOADPROMPTS3D("Latitude stop   (degrees)");
  1923.       LOADPROMPTS3D("Radius scaling factor in pct");
  1924.    }
  1925.    else
  1926.    {
  1927.       k = -1;
  1928.       if (!RAY)
  1929.       {
  1930.          LOADPROMPTS3D("X-axis rotation in degrees");
  1931.          LOADPROMPTS3D("Y-axis rotation in degrees");
  1932.          LOADPROMPTS3D("Z-axis rotation in degrees");
  1933.       }
  1934.       LOADPROMPTS3D("X-axis scaling factor in pct");
  1935.       LOADPROMPTS3D("Y-axis scaling factor in pct");
  1936.    }
  1937.    k = -1;
  1938.    if (!(RAY && !SPHERE))
  1939.    {
  1940.       uvalues[++k].uval.ival   = XROT     ;
  1941.       uvalues[k].type = 'i';
  1942.       uvalues[++k].uval.ival   = YROT     ;
  1943.       uvalues[k].type = 'i';
  1944.       uvalues[++k].uval.ival   = ZROT     ;
  1945.       uvalues[k].type = 'i';
  1946.    }
  1947.    uvalues[++k].uval.ival   = XSCALE    ;
  1948.    uvalues[k].type = 'i';
  1949.  
  1950.    uvalues[++k].uval.ival   = YSCALE    ;
  1951.    uvalues[k].type = 'i';
  1952.  
  1953.    LOADPROMPTS3D("Surface Roughness scaling factor in pct");
  1954.    uvalues[k].type = 'i';
  1955.    uvalues[k].uval.ival = ROUGH     ;
  1956.  
  1957.    LOADPROMPTS3D("'Water Level' (minimum color value)");
  1958.    uvalues[k].type = 'i';
  1959.    uvalues[k].uval.ival = WATERLINE ;
  1960.  
  1961.    if(!RAY)
  1962.    {
  1963.       LOADPROMPTS3D("Perspective distance [1 - 999, 0 for no persp])");
  1964.       uvalues[k].type = 'i';
  1965.       uvalues[k].uval.ival = ZVIEWER     ;
  1966.  
  1967.       LOADPROMPTS3D("X shift with perspective (positive = right)");
  1968.       uvalues[k].type = 'i';
  1969.       uvalues[k].uval.ival = XSHIFT    ;
  1970.    
  1971.       LOADPROMPTS3D("Y shift with perspective (positive = up   )");
  1972.       uvalues[k].type = 'i';
  1973.       uvalues[k].uval.ival = YSHIFT    ;
  1974.    
  1975.       LOADPROMPTS3D("Image non-perspective X adjust (positive = right)");
  1976.       uvalues[k].type = 'i';
  1977.       uvalues[k].uval.ival = xtrans    ;
  1978.    
  1979.       LOADPROMPTS3D("Image non-perspective Y adjust (positive = up)");
  1980.       uvalues[k].type = 'i';
  1981.       uvalues[k].uval.ival = ytrans    ;
  1982.    
  1983.       LOADPROMPTS3D("First transparent color");
  1984.       uvalues[k].type = 'i';
  1985.       uvalues[k].uval.ival = transparent[0];
  1986.    
  1987.       LOADPROMPTS3D("Last transparent color");
  1988.       uvalues[k].type = 'i';
  1989.       uvalues[k].uval.ival = transparent[1];
  1990.    }
  1991.  
  1992.    LOADPROMPTS3D("Randomize Colors      (0 - 7, '0' disables)");
  1993.    uvalues[k].type = 'i';
  1994.    uvalues[k++].uval.ival = RANDOMIZE;
  1995.  
  1996.    if (SPHERE)
  1997.       s = s1;
  1998.    else
  1999.       s = s2;
  2000.  
  2001.    helpmode = HELP3DPARMS;
  2002.    k = fullscreen_prompt(s,k,prompts3d,uvalues,0,NULL);
  2003.    helpmode = oldhelpmode;
  2004.    if (k < 0)
  2005.       goto restart_1;
  2006.  
  2007.    k = 0;
  2008.    if (!(RAY && !SPHERE))
  2009.    {
  2010.       XROT    = uvalues[k++].uval.ival;
  2011.       YROT    = uvalues[k++].uval.ival;
  2012.       ZROT    = uvalues[k++].uval.ival;
  2013.    }
  2014.    XSCALE     = uvalues[k++].uval.ival;
  2015.    YSCALE     = uvalues[k++].uval.ival;
  2016.    ROUGH      = uvalues[k++].uval.ival;
  2017.    WATERLINE  = uvalues[k++].uval.ival;
  2018.    if (!RAY)
  2019.    {
  2020.       ZVIEWER = uvalues[k++].uval.ival;
  2021.    XSHIFT     = uvalues[k++].uval.ival;
  2022.    YSHIFT     = uvalues[k++].uval.ival;
  2023.    xtrans     = uvalues[k++].uval.ival;
  2024.    ytrans     = uvalues[k++].uval.ival;
  2025.    transparent[0] = uvalues[k++].uval.ival;
  2026.    transparent[1] = uvalues[k++].uval.ival;
  2027.    }
  2028.    RANDOMIZE  = uvalues[k++].uval.ival;
  2029.    if (RANDOMIZE >= 7) RANDOMIZE = 7;
  2030.    if (RANDOMIZE <= 0) RANDOMIZE = 0;
  2031.  
  2032.    if ((Targa_Out || ILLUMINE || RAY))
  2033.     if(get_light_params())
  2034.         goto restart_3;
  2035. return(0);
  2036. }
  2037.  
  2038. /* --------------------------------------------------------------------- */
  2039. static int get_light_params()
  2040. {
  2041.    static FCODE hdg[]={"Light Source Parameters"};
  2042.    char far *prompts3d[13];
  2043.    struct fullscreenvalues uvalues[13];
  2044.  
  2045.    int k;
  2046.    int oldhelpmode;
  2047.  
  2048.    /* defaults go here */
  2049.  
  2050.    k = -1;
  2051.  
  2052.    if (ILLUMINE || RAY)
  2053.    {
  2054.    LOADPROMPTS3D("X value light vector");
  2055.    uvalues[k].type = 'i';
  2056.    uvalues[k].uval.ival = XLIGHT    ;
  2057.  
  2058.    LOADPROMPTS3D("Y value light vector");
  2059.    uvalues[k].type = 'i';
  2060.    uvalues[k].uval.ival = YLIGHT    ;
  2061.  
  2062.    LOADPROMPTS3D("Z value light vector");
  2063.    uvalues[k].type = 'i';
  2064.    uvalues[k].uval.ival = ZLIGHT    ;
  2065.  
  2066.         if (!RAY)
  2067.         {
  2068.    LOADPROMPTS3D("Light Source Smoothing Factor");
  2069.    uvalues[k].type = 'i';
  2070.    uvalues[k].uval.ival = LIGHTAVG  ;
  2071.  
  2072.    LOADPROMPTS3D("Ambient");
  2073.    uvalues[k].type = 'i';
  2074.    uvalues[k].uval.ival = Ambient;
  2075.         }
  2076.    }
  2077.  
  2078.    if (Targa_Out && !RAY)
  2079.    {
  2080.     LOADPROMPTS3D("Haze Factor        (0 - 100, '0' disables)");
  2081.     uvalues[k].type = 'i';
  2082.     uvalues[k].uval.ival= haze;
  2083.  
  2084.         if (!Targa_Overlay)
  2085.     check_writefile(light_name,".tga");
  2086.       LOADPROMPTS3D("Targa File Name  (Assume .tga)");
  2087.     uvalues[k].type = 's';
  2088.     strcpy(uvalues[k].uval.sval,light_name);
  2089.  
  2090.       LOADPROMPTS3D("Back Ground Color (0 - 255)");
  2091.       uvalues[k].type = '*';
  2092.  
  2093.       LOADPROMPTS3D("   Red");
  2094.       uvalues[k].type = 'i';
  2095.       uvalues[k].uval.ival = (int)back_color[0];
  2096.  
  2097.       LOADPROMPTS3D("   Green");
  2098.       uvalues[k].type = 'i';
  2099.       uvalues[k].uval.ival = (int)back_color[1];
  2100.  
  2101.       LOADPROMPTS3D("   Blue");
  2102.       uvalues[k].type = 'i';
  2103.       uvalues[k].uval.ival = (int)back_color[2];
  2104.  
  2105.       LOADPROMPTS3D("Overlay Targa File? (Y/N)");
  2106.       uvalues[k].type = 'y';
  2107.       uvalues[k].uval.ch.val = Targa_Overlay;
  2108.  
  2109.    }
  2110.  
  2111.    LOADPROMPTS3D("");
  2112.  
  2113.    oldhelpmode = helpmode;
  2114.    helpmode = HELP3DLIGHT;
  2115.    k = fullscreen_prompt(hdg,k,prompts3d,uvalues,0,NULL);
  2116.    helpmode = oldhelpmode;
  2117.    if (k < 0)
  2118.       return(-1);
  2119.  
  2120.    k = 0;
  2121.    if (ILLUMINE)
  2122.    {
  2123.       XLIGHT   = uvalues[k++].uval.ival;
  2124.       YLIGHT   = uvalues[k++].uval.ival;
  2125.       ZLIGHT   = uvalues[k++].uval.ival;
  2126.       if (!RAY)
  2127.         {
  2128.       LIGHTAVG = uvalues[k++].uval.ival;
  2129.       Ambient  = uvalues[k++].uval.ival;
  2130.       if (Ambient >= 100) Ambient = 100;
  2131.       if (Ambient <= 0) Ambient = 0;
  2132.         }
  2133.    }
  2134.  
  2135.    if (Targa_Out && !RAY)
  2136.    {
  2137.     haze  =  uvalues[k++].uval.ival;
  2138.     if (haze >= 100) haze = 100;
  2139.     if (haze <= 0) haze = 0;
  2140.         strcpy(light_name,uvalues[k++].uval.sval);
  2141.         /* In case light_name conflicts with an existing name it is checked
  2142.             again in line3d */
  2143.         k++;
  2144.         back_color[0] = (char)(uvalues[k++].uval.ival % 255);
  2145.         back_color[1] = (char)(uvalues[k++].uval.ival % 255);
  2146.         back_color[2] = (char)(uvalues[k++].uval.ival % 255);
  2147.         Targa_Overlay = uvalues[k].uval.ch.val;
  2148.    }
  2149.    return(0);
  2150. }
  2151.  
  2152. /* --------------------------------------------------------------------- */
  2153.  
  2154.  
  2155. static int check_mapfile()
  2156. {
  2157.    int askflag = 0;
  2158.    int i,oldhelpmode;
  2159.    if(dontreadcolor)
  2160.       return(0);
  2161.    strcpy(temp1,"*");
  2162.    if (mapset)
  2163.       strcpy(temp1,MAP_name);
  2164.    if (!(glassestype == 1 || glassestype == 2))
  2165.       askflag = 1;
  2166.    else
  2167.       merge_pathnames(temp1,funnyglasses_map_name,0);
  2168.    
  2169.    for(;;) {
  2170.       if (askflag) {
  2171.          static FCODE msg[] = {"\
  2172. Enter name of .MAP file to use,\n\
  2173. or '*' to use palette from the image to be loaded."};
  2174.      oldhelpmode = helpmode;
  2175.      helpmode = -1;
  2176.      i = field_prompt(0,msg,NULL,temp1,60,NULL);
  2177.      helpmode = oldhelpmode;
  2178.      if (i < 0)
  2179.         return(-1);
  2180.          if (temp1[0] == '*') {
  2181.             mapset = 0;
  2182.             break;
  2183.          }
  2184.       }
  2185.       memcpy(olddacbox,dacbox,256*3); /* save the DAC */
  2186.       i = ValidateLuts(temp1);
  2187.       memcpy(dacbox,olddacbox,256*3); /* restore the DAC */
  2188.       if (i != 0) { /* Oops, somethings wrong */
  2189.          askflag = 1;
  2190.          continue;
  2191.          }
  2192.       mapset = 1;
  2193.       merge_pathnames(MAP_name,temp1,0);
  2194.       break;
  2195.       }
  2196.    return(0);
  2197. }
  2198.  
  2199. static int get_funny_glasses_params()
  2200. {
  2201.    static FCODE hdg[]={"Funny Glasses Parameters"};
  2202.    char far *prompts3d[10];
  2203.  
  2204.    struct fullscreenvalues uvalues[10];
  2205.  
  2206.    int k;
  2207.    int oldhelpmode;
  2208.  
  2209.    /* defaults */
  2210.    if(ZVIEWER == 0)
  2211.       ZVIEWER = 150;
  2212.    if(eyeseparation == 0)
  2213.    {
  2214.       if(fractype==IFS3D || fractype==LLORENZ3D || fractype==FPLORENZ3D)
  2215.       {
  2216.      eyeseparation =  2;
  2217.      xadjust       = -2;
  2218.       }
  2219.       else
  2220.       {
  2221.      eyeseparation =  3;
  2222.      xadjust       =  0;
  2223.       }
  2224.    }
  2225.  
  2226.    if(glassestype == 1)
  2227.       strcpy(funnyglasses_map_name,Glasses1Map);
  2228.    else if(glassestype == 2)
  2229.    {
  2230.       if(FILLTYPE == -1)
  2231.      strcpy(funnyglasses_map_name,"grid.map");
  2232.       else
  2233.       {
  2234.      strcpy(funnyglasses_map_name,Glasses1Map);
  2235.      funnyglasses_map_name[7] = '2';
  2236.       }
  2237.    }
  2238.  
  2239.    k = -1;
  2240.    LOADPROMPTS3D("Interocular distance (as % of screen)");
  2241.    uvalues[k].type = 'i';
  2242.    uvalues[k].uval.ival= eyeseparation;
  2243.  
  2244.    LOADPROMPTS3D("Convergence adjust (positive = spread greater)");
  2245.    uvalues[k].type = 'i';
  2246.    uvalues[k].uval.ival = xadjust;
  2247.  
  2248.    LOADPROMPTS3D("Left  red image crop (% of screen)");
  2249.    uvalues[k].type = 'i';
  2250.    uvalues[k].uval.ival = red_crop_left;
  2251.  
  2252.    LOADPROMPTS3D("Right red image crop (% of screen)");
  2253.    uvalues[k].type = 'i';
  2254.    uvalues[k].uval.ival = red_crop_right;
  2255.  
  2256.    LOADPROMPTS3D("Left  blue image crop (% of screen)");
  2257.    uvalues[k].type = 'i';
  2258.    uvalues[k].uval.ival = blue_crop_left;
  2259.  
  2260.    LOADPROMPTS3D("Right blue image crop (% of screen)");
  2261.    uvalues[k].type = 'i';
  2262.    uvalues[k].uval.ival = blue_crop_right;
  2263.  
  2264.    LOADPROMPTS3D("Red brightness factor (%)");
  2265.    uvalues[k].type = 'i';
  2266.    uvalues[k].uval.ival = red_bright;
  2267.  
  2268.    LOADPROMPTS3D("Blue brightness factor (%)");
  2269.    uvalues[k].type = 'i';
  2270.    uvalues[k].uval.ival = blue_bright;
  2271.  
  2272.    if(glassestype == 1 || glassestype == 2)
  2273.    {
  2274.       LOADPROMPTS3D("Map File name");
  2275.       uvalues[k].type = 's';
  2276.       strcpy(uvalues[k].uval.sval,funnyglasses_map_name);
  2277.    }
  2278.  
  2279.    oldhelpmode = helpmode;
  2280.    helpmode = HELP3DGLASSES;
  2281.    k = fullscreen_prompt(hdg,k+1,prompts3d,uvalues,0,NULL);
  2282.    helpmode = oldhelpmode;
  2283.    if (k < 0)
  2284.       return(-1);
  2285.  
  2286.    k = 0;
  2287.    eyeseparation   =  uvalues[k++].uval.ival;
  2288.    xadjust       =  uvalues[k++].uval.ival;
  2289.    red_crop_left   =  uvalues[k++].uval.ival;
  2290.    red_crop_right  =  uvalues[k++].uval.ival;
  2291.    blue_crop_left  =  uvalues[k++].uval.ival;
  2292.    blue_crop_right =  uvalues[k++].uval.ival;
  2293.    red_bright       =  uvalues[k++].uval.ival;
  2294.    blue_bright       =  uvalues[k++].uval.ival;
  2295.  
  2296.    if(glassestype == 1 || glassestype == 2)
  2297.       strcpy(funnyglasses_map_name,uvalues[k].uval.sval);
  2298.    return(0);
  2299. }
  2300.  
  2301. void setbailoutformula(enum bailouts test) {
  2302.  
  2303.    switch(test) {
  2304.      case Mod:
  2305.      default:{
  2306.          if (fpu >= 287 && debugflag != 72)    /* Fast 287 math */
  2307.            floatbailout = (int (near *)(void))asmfpMODbailout;
  2308.          else
  2309.            floatbailout = (int (near *)(void))fpMODbailout;
  2310.          if (cpu >=386 && debugflag != 8088)    /* Fast 386 math */
  2311.            longbailout = (int (near *)(void))asm386lMODbailout;
  2312.          else
  2313.            longbailout = (int (near *)(void))asmlMODbailout;
  2314.          bignumbailout = (int (near *)(void))bnMODbailout;
  2315.          bigfltbailout = (int (near *)(void))bfMODbailout;
  2316.          break;}
  2317.      case Real: {
  2318.          if (fpu >= 287 && debugflag != 72)    /* Fast 287 math */
  2319.            floatbailout = (int (near *)(void))asmfpREALbailout;
  2320.          else
  2321.            floatbailout = (int (near *)(void))fpREALbailout;
  2322.          if (cpu >=386 && debugflag != 8088)    /* Fast 386 math */
  2323.            longbailout = (int (near *)(void))asm386lREALbailout;
  2324.          else
  2325.            longbailout = (int (near *)(void))asmlREALbailout;
  2326.          bignumbailout = (int (near *)(void))bnREALbailout;
  2327.          bigfltbailout = (int (near *)(void))bfREALbailout;
  2328.          break;}
  2329.      case Imag:{
  2330.          if (fpu >= 287 && debugflag != 72)    /* Fast 287 math */
  2331.            floatbailout = (int (near *)(void))asmfpIMAGbailout;
  2332.          else
  2333.            floatbailout = (int (near *)(void))fpIMAGbailout;
  2334.          if (cpu >=386 && debugflag != 8088)    /* Fast 386 math */
  2335.            longbailout = (int (near *)(void))asm386lIMAGbailout;
  2336.          else
  2337.            longbailout = (int (near *)(void))asmlIMAGbailout;
  2338.          bignumbailout = (int (near *)(void))bnIMAGbailout;
  2339.          bigfltbailout = (int (near *)(void))bfIMAGbailout;
  2340.          break;}
  2341.      case Or:{
  2342.          if (fpu >= 287 && debugflag != 72)    /* Fast 287 math */
  2343.            floatbailout = (int (near *)(void))asmfpORbailout;
  2344.          else
  2345.            floatbailout = (int (near *)(void))fpORbailout;
  2346.          if (cpu >=386 && debugflag != 8088)    /* Fast 386 math */
  2347.            longbailout = (int (near *)(void))asm386lORbailout;
  2348.          else
  2349.            longbailout = (int (near *)(void))asmlORbailout;
  2350.          bignumbailout = (int (near *)(void))bnORbailout;
  2351.          bigfltbailout = (int (near *)(void))bfORbailout;
  2352.          break;}
  2353.      case And:{
  2354.          if (fpu >= 287 && debugflag != 72)    /* Fast 287 math */
  2355.            floatbailout = (int (near *)(void))asmfpANDbailout;
  2356.          else
  2357.            floatbailout = (int (near *)(void))fpANDbailout;
  2358.          if (cpu >=386 && debugflag != 8088)    /* Fast 386 math */
  2359.            longbailout = (int (near *)(void))asm386lANDbailout;
  2360.          else
  2361.            longbailout = (int (near *)(void))asmlANDbailout;
  2362.          bignumbailout = (int (near *)(void))bnANDbailout;
  2363.          bigfltbailout = (int (near *)(void))bfANDbailout;
  2364.          break;}
  2365.    }
  2366. }
  2367.